package com.smile.frame.websocket.netty.service.controller;

import com.smile.frame.common.result.Result;
import com.smile.frame.websocket.netty.service.dto.ClientInfoDTO;
import com.smile.frame.websocket.netty.service.dto.SendOtherClientDTO;
import com.smile.frame.websocket.netty.service.enums.CmdEnum;
import com.smile.frame.websocket.netty.service.repository.ChannelRepository;
import com.smile.frame.websocket.netty.service.repository.ClientRepository;
import com.smile.frame.websocket.netty.service.util.BuilderMessageUtil;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * @author LGC
 */
@Slf4j
@Api(tags = "WebsocketController")
@RestController
public class WebsocketController {

    /**
     * websocket集群中一个客户端向其他客户端主动发送消息
     */
    @PostMapping(value = "/websocket/sendOtherClient", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "sendOtherClient")
    public Result<String> sendOtherClient(@Validated @RequestBody SendOtherClientDTO dto) {
        //获取所有连接的客户端,如果是集群环境使用redis的hash数据类型存储即可
        Map<String, Channel> channelMap = ChannelRepository.CHANNEL_MAP;
        log.info("channelMap:{}", channelMap);
        //获取与用户主键绑定的channel,如果是集群环境使用redis的hash数据类型存储即可
        Map<String, String> clientMap = ClientRepository.CLIENT_MAP;
        log.info("clientMap:{}", clientMap);

        //解决问题六,websocket集群中一个客户端向其他客户端主动发送消息，如何实现？
        clientMap.forEach((k, v) -> {
            if (dto.getOtherClient().contains(v)) {
                Channel channel = channelMap.get(k);
                channel.eventLoop().execute(() -> {
                    ClientInfoDTO clientInfo = new ClientInfoDTO();
                    clientInfo.setClientId(v);
                    TextWebSocketFrame message = BuilderMessageUtil.buildStringMessage(clientInfo, CmdEnum.DATA, dto.getClient() + "发来的信息" + System.currentTimeMillis());
                    channel.writeAndFlush(message);
                });
            }
        });
        return Result.ok("在线人数" + channelMap.size());
    }
}
